<script lang="ts" setup name="XtxCity">
// 城市列表类型
export type AreaList = {
  code: string
  level: number
  name: string
  areaList: AreaList[]
}
export type ChangeResult = {
  provinceCode: string;
  provinceName: string;
  cityCode: string;
  cityName: string;
  countyCode: string;
  countyName: string;
}

import { ref, watch } from 'vue';
import axios from 'axios'
import { onClickOutside } from '@vueuse/core'

// 父传子 
defineProps({
  userAdress: {
    type: String,
    default: '上海市 上海市 浦东新区'
  }
})

// 组件子传父 
const emit = defineEmits<{
  (e: 'changeCity', value: ChangeResult): void
}>()

const active = ref(false)
const cityList = ref<AreaList[]>()
const cacehList = ref<AreaList[]>()
const target = ref(null)
// 选择城市
const changeResult = ref<ChangeResult>({
  provinceCode: '',
  provinceName: '',
  cityCode: '',
  cityName: '',
  countyCode: '',
  countyName: ''
})

// 城市数据，从阿里云服务器获取，直接在组件内获取
const fetchAreaList = async () => {
  try {
    const res = await axios.get<AreaList[]>('https://yjy-oss-files.oss-cn-zhangjiakou.aliyuncs.com/tuxian/area.json')
    cityList.value = res.data
    // 用cacehList 存一下数据
    cacehList.value = res.data
  } catch (error) {
    console.error(error);
  }
}
fetchAreaList()

// 点击切换
const handleToggle = () => {
  active.value = !active.value
}

// 利用事件冒泡，解决点击外层，可以关闭弹窗和下拉框，=> VueUse 的 onClicktSide 方法
onClickOutside(target, (e) => {
  active.value = false
})

// 处理选择
const handleSelect = (val: AreaList) => {
  if (val.level === 0) {
    changeResult.value.provinceCode = val.code
    changeResult.value.provinceName = val.name
    cityList.value = val.areaList
  } else if (val.level === 1) {
    changeResult.value.cityCode = val.code
    changeResult.value.cityName = val.name
    cityList.value = val.areaList
  } else if (val.level === 2) {
    changeResult.value.countyCode = val.code
    changeResult.value.countyName = val.name
    active.value = false

    // 如果选择了 val.level === 2 就只解子传父给外面的组件使用数据
    emit('changeCity', changeResult.value)
  }
}

// 如果只要选择的弹框关闭了就需要 利用cacheList重置数据
watch(
  active,
  val => {
    // 每次只要是弹窗打开就需要重置 countyName数据
    if (val) {
      changeResult.value.provinceCode = ''
      changeResult.value.provinceName = ''
      changeResult.value.cityCode = ''
      changeResult.value.cityName = ''
      changeResult.value.countyCode = ''
      changeResult.value.countyName = ''
    }
    // 如果弹窗关闭重置 cityList数据
    cityList.value = cacehList.value
  }
)
</script>

<template>
  <div class="xtx-city" ref="target">
    <div class="select" @click="handleToggle" :class="{ active: active }">
      <span class="value" v-if="userAdress">{{ userAdress }}</span>
      <span class="placeholder" v-else>请选择配送地址</span>
      <i class="iconfont icon-angle-down"></i>
    </div>
    <div class="option" v-show="active">
      <span class="ellipsis" v-for="item in cityList" :key="item.code" @click="handleSelect(item)">{{
        item.name
      }}</span>
    </div>
  </div>
</template>

<style scoped lang="less">
.xtx-city {
  display: inline-block;
  position: relative;
  z-index: 400;

  .select {
    border: 1px solid #e4e4e4;
    height: 30px;
    padding: 0 5px;
    line-height: 28px;
    cursor: pointer;

    &.active {
      background: #fff;
    }

    .placeholder {
      color: #999;
    }

    .value {
      color: #666;
      font-size: 12px;
    }

    i {
      font-size: 12px;
      margin-left: 5px;
    }
  }

  .option {
    width: 542px;
    border: 1px solid #e4e4e4;
    position: absolute;
    left: 0;
    top: 29px;
    background: #fff;
    min-height: 30px;
    line-height: 30px;
    display: flex;
    flex-wrap: wrap;
    padding: 10px;

    >span {
      width: 130px;
      text-align: center;
      cursor: pointer;
      border-radius: 4px;
      padding: 0 3px;

      &:hover {
        background: #f5f5f5;
      }
    }
  }
}
</style>